/*****************************************************************************
	SNEGA UTILITIES 0.7a
	Copyright (C) 2009, Xiaohan Tian (snega0223)
	
	http://code.google.com/p/snega-utilities/
	
	This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License(LGPL) as
	published by the Free Software Foundation, either version 3 of the 
	License, or(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.
	
	You should have received a copy of the GNU Lesser General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/

package org.sng.util.web;

import java.io.*;
import java.util.*;

import java.lang.reflect.*;

import javax.servlet.*;
import javax.servlet.http.*;

import org.sng.util.slog.*;
import org.sng.util.web.elmt.*;
import org.sng.util.web.parser.*;

public class WebPageProcessor extends HttpServlet {

	private static final long serialVersionUID = 1L;
	
	private static HashMap<String, WebPageMaker> m_servletMap = new HashMap<String, WebPageMaker>();
	
	public static void AddMaker(String svlt, WebPageMaker o)
	{
		WebPageProcessor.m_servletMap.put(svlt, o);
	}
	
	public static void RemoveMaker(String svlt)
	{
		WebPageProcessor.m_servletMap.remove(svlt);
	}
	
	@SuppressWarnings("deprecation")
	public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
	{
		response.setCharacterEncoding("UTF-8");

		String url = request.getServletPath();
		
		int namePos = url.lastIndexOf("/");
		String path = url.substring(0, namePos + 1);
		String name = url.substring(namePos + 1, url.length() - 8);
		
		Node node = null;
		
		String [] strs = name.split("-");
		if (strs.length < 2)
		{
			strs = new String[2];
			
			//throw new ServletException("Request url doesn't meet standard.");
			int namePos2 = path.substring(0, path.length() - 1).lastIndexOf("/");
			path = url.substring(0, namePos2 + 1);
			
			strs[0] = url.substring(namePos2 + 1, namePos);
			strs[1] = name;
			
			//name = strs[0] + "-" + strs[1];		// For post to same path, this name doesn't need to change
		}
		// strs[0] = WebPageMaker name
		// strs[1] = Page name
		
		WebPageMaker maker = null;
		SLog.println(path + "|" + strs[1]);
		String event = request.getParameter("event");
		
		if (event == null)
		{
			response.setContentType("text/html");
			
			SLog.println("Reuqest URL: " + url);
			
			// Process page and output
			try {
				maker = WebPageProcessor.m_servletMap.get(strs[0]);
				
				FileInputStream src = new FileInputStream(request.getRealPath(path + strs[1] + ".webpage") + ".html");
				InputStreamReader file = new InputStreamReader(src, "UTF-8");
				
				node = Parser.Parse(file, maker);
			} catch (Exception e) {
				SLog.println("Error in parsing file: " + request.getRealPath(url) + ".html");
				e.printStackTrace();
				
				return;
			}
			
			try {
				RuntimeEnvironment re = new RuntimeEnvironment(request, response, maker, node);
				
				re.SetUrl(name + ".webpage");
				//re.SetBrowserType(browserType);
				
				if (maker != null)
				{
					try {
						Method method = null;
						
						method = Class.forName(maker.getClass().getName()).getMethod("on" + strs[1] + "Create", Class.forName("org.sng.util.web.elmt.RuntimeEnvironment"));
					
						method.invoke(maker, re);
					} catch (NoSuchMethodException e) {
						SLog.println(strs[0] + " - Skipped page create event: on" + strs[1] + "Create");
					}
					
					maker.Make(re);
				}
			} catch (Exception e) {
				SLog.println("Error in execution file: " + request.getRealPath(url) + ".html");
				e.printStackTrace();
			}
		}
		else
		{
			response.setContentType("text/xml");
			
			SLog.println("Process: " + url + " [ Id = " + request.getParameter("id") + ", Event = " + event + " ]");
			
			maker = WebPageProcessor.m_servletMap.get(strs[0]);
			
			String id = request.getParameter("id");
			
			// Process event and response
			try {
				RuntimeEnvironment re = new RuntimeEnvironment(request, response, maker, new Node());
				//re.SetBrowserType(browserType);
				
				maker.Process(re, request);
				
				Method method = null;
				String callback;
				
				try {
					if ((callback = request.getParameter("callback")) != null) {
						method = Class.forName(maker.getClass().getName()).getMethod(callback, Class.forName("org.sng.util.web.elmt.RuntimeEnvironment"));
					}
					else {
						method = Class.forName(maker.getClass().getName()).getMethod("on" + id + event, Class.forName("org.sng.util.web.elmt.RuntimeEnvironment"));
					}
					
					method.invoke(maker, re);
				} catch (NoSuchMethodException e) {
					SLog.println(strs[0] + " - Skipped event event \"" + event + "\" of node \"" + id + "\" in url: " + url);
				}
			} catch (Exception e) {
				// TODO: handle exception
				SLog.println("Error in handling event \"" + event + "\" of node \"" + id + "\" in url: " + url);
				e.printStackTrace();
			}
		}
	}

}
